νμ₯ κ°λ₯νκ³ ν¨μ¨μ μΈ λ°μ΄ν° κ²μ μμ€ν ꡬμΆμ μν API νμ΄μ§λ€μ΄μ μ λ΅, ꡬν ν¨ν΄, λͺ¨λ² μ¬λ‘μ λν μ’ ν© κ°μ΄λμ λλ€.
API νμ΄μ§λ€μ΄μ : νμ₯ κ°λ₯ν λ°μ΄ν° κ²μμ μν ꡬν ν¨ν΄
μ€λλ μ λ°μ΄ν° μ€μ¬ μΈκ³μμ API(μ ν리μΌμ΄μ νλ‘κ·Έλλ° μΈν°νμ΄μ€)λ μλ§μ μ ν리μΌμ΄μ μ μ€μΆ μν μ ν©λλ€. APIλ μλ‘ λ€λ₯Έ μμ€ν κ°μ μνν ν΅μ κ³Ό λ°μ΄ν° κ΅νμ κ°λ₯νκ² ν©λλ€. κ·Έλ¬λ λμ©λ λ°μ΄ν°μ μ λ€λ£° λ, λ¨μΌ μμ²μΌλ‘ λͺ¨λ λ°μ΄ν°λ₯Ό κ²μνλ κ²μ μ±λ₯ λ³λͺ© νμ, λλ¦° μλ΅ μκ°, κ·Έλ¦¬κ³ μ’μ§ μμ μ¬μ©μ κ²½νμΌλ‘ μ΄μ΄μ§ μ μμ΅λλ€. λ°λ‘ μ΄ μ§μ μμ API νμ΄μ§λ€μ΄μ μ΄ νμν©λλ€. νμ΄μ§λ€μ΄μ μ λκ·λͺ¨ λ°μ΄ν°μ μ λ μκ³ κ΄λ¦¬νκΈ° μ¬μ΄ λ©μ΄λ¦¬(chunk)λ‘ λλμ΄ ν΄λΌμ΄μΈνΈκ° μ¬λ¬ λ²μ μμ²μ ν΅ν΄ λ°μ΄ν°λ₯Ό κ²μν μ μλλ‘ νλ μ€μν κΈ°μ μ λλ€.
μ΄ μ’ ν© κ°μ΄λμμλ νμ₯ κ°λ₯νκ³ ν¨μ¨μ μΈ λ°μ΄ν° κ²μ μμ€ν μ ꡬμΆνκΈ° μν λ€μν API νμ΄μ§λ€μ΄μ μ λ΅, ꡬν ν¨ν΄ λ° λͺ¨λ² μ¬λ‘λ₯Ό μ΄ν΄λ΄ λλ€. κ° μ κ·Ό λ°©μμ μ₯λ¨μ μ κΉμ΄ νκ³ λ€κ³ , νΉμ μꡬμ¬νμ λ§λ μ¬λ°λ₯Έ νμ΄μ§λ€μ΄μ μ λ΅μ μ ννκΈ° μν μ€μ©μ μΈ μμ μ κ³ λ €μ¬νμ μ 곡ν κ²μ λλ€.
API νμ΄μ§λ€μ΄μ μ μ μ€μνκ°?
ꡬν μΈλΆ μ¬νμ μ΄ν΄λ³΄κΈ° μ μ, μ νμ΄μ§λ€μ΄μ μ΄ API κ°λ°μ κ·Έν λ‘ μ€μνμ§ μ΄ν΄ν΄ λ΄ μλ€:
- μ±λ₯ ν₯μ: κ° μμ²μμ λ°νλλ λ°μ΄ν° μμ μ νν¨μΌλ‘μ¨, νμ΄μ§λ€μ΄μ μ μλ²μ μ²λ¦¬ λΆνλ₯Ό μ€μ΄κ³ λ€νΈμν¬ λμν μ¬μ©μ μ΅μνν©λλ€. μ΄λ λ λΉ λ₯Έ μλ΅ μκ°κ³Ό λ λ°μμ μΈ μ¬μ©μ κ²½νμΌλ‘ μ΄μ΄μ§λλ€.
- νμ₯μ±: νμ΄μ§λ€μ΄μ μ ν΅ν΄ APIλ μ±λ₯μ μν₯μ μ£Όμ§ μκ³ λκ·λͺ¨ λ°μ΄ν°μ μ μ²λ¦¬ν μ μμ΅λλ€. λ°μ΄ν°κ° μ¦κ°ν¨μ λ°λΌ μ¦κ°λ λΆνλ₯Ό μμ©νκΈ° μν΄ API μΈνλΌλ₯Ό μ½κ² νμ₯ν μ μμ΅λλ€.
- λ©λͺ¨λ¦¬ μλΉ κ°μ: λ°©λν λ°μ΄ν°μ μ λ€λ£° λ, λͺ¨λ λ°μ΄ν°λ₯Ό ν λ²μ λ©λͺ¨λ¦¬μ λ‘λνλ©΄ μλ² λ¦¬μμ€λ₯Ό λΉ λ₯΄κ² μμ§μν¬ μ μμ΅λλ€. νμ΄μ§λ€μ΄μ μ λ°μ΄ν°λ₯Ό λ μμ λ©μ΄λ¦¬λ‘ μ²λ¦¬νμ¬ λ©λͺ¨λ¦¬ μλΉλ₯Ό μ€μ΄λ λ° λμμ΄ λ©λλ€.
- λ λμ μ¬μ©μ κ²½ν: μ¬μ©μλ λ°μ΄ν°μ μνΈμμ©μ μμνκΈ° μ μ μ 체 λ°μ΄ν°μ μ΄ λ‘λλ λκΉμ§ κΈ°λ€λ¦΄ νμκ° μμ΅λλ€. νμ΄μ§λ€μ΄μ μ ν΅ν΄ μ¬μ©μλ λ μ§κ΄μ μ΄κ³ ν¨μ¨μ μΈ λ°©μμΌλ‘ λ°μ΄ν°λ₯Ό νμν μ μμ΅λλ€.
- μλ μ ν(Rate Limiting) κ³ λ €μ¬ν: λ§μ API μ 곡μ 체λ λ¨μ©μ λ°©μ§νκ³ κ³΅μ ν μ¬μ©μ 보μ₯νκΈ° μν΄ μλ μ νμ ꡬνν©λλ€. νμ΄μ§λ€μ΄μ μ ν΅ν΄ ν΄λΌμ΄μΈνΈλ λ μμ μμ²μ μ¬λ¬ λ² λ§λ€μ΄ μλ μ νμ μ μ½ λ΄μμ λκ·λͺ¨ λ°μ΄ν°μ μ κ²μν μ μμ΅λλ€.
μΌλ°μ μΈ API νμ΄μ§λ€μ΄μ μ λ΅
API νμ΄μ§λ€μ΄μ μ ꡬννλ λ°μλ λͺ κ°μ§ μΌλ°μ μΈ μ λ΅μ΄ μμΌλ©°, κ°κΈ° μ₯λ¨μ μ΄ μμ΅λλ€. κ°μ₯ μΈκΈ° μλ λͺ κ°μ§ μ κ·Ό λ°©μμ μ΄ν΄λ³΄κ² μ΅λλ€:
1. μ€νμ κΈ°λ° νμ΄μ§λ€μ΄μ (Offset-Based Pagination)
μ€νμ κΈ°λ° νμ΄μ§λ€μ΄μ μ κ°μ₯ κ°λ¨νκ³ λ리 μ¬μ©λλ νμ΄μ§λ€μ΄μ μ λ΅μ λλ€. API μμ²μ μ€νμ (μμμ )κ³Ό 리미νΈ(κ²μν νλͺ© μ)λ₯Ό μ§μ νλ λ°©μμ λλ€.
μμ:
GET /users?offset=0&limit=25
μ΄ μμ²μ 첫 25λͺ μ μ¬μ©μ(첫 λ²μ§Έ μ¬μ©μλΆν° μμ)λ₯Ό κ²μν©λλ€. λ€μ νμ΄μ§μ μ¬μ©μλ₯Ό κ²μνλ €λ©΄ μ€νμ μ μ¦κ°μν€λ©΄ λ©λλ€:
GET /users?offset=25&limit=25
μ₯μ :
- ꡬννκ³ μ΄ν΄νκΈ° μ½μ΅λλ€.
- λλΆλΆμ λ°μ΄ν°λ² μ΄μ€μ νλ μμν¬μμ λ리 μ§μλ©λλ€.
λ¨μ :
- μ±λ₯ λ¬Έμ : μ€νμ μ΄ μ¦κ°ν μλ‘ λ°μ΄ν°λ² μ΄μ€λ λ λ§μ μμ λ μ½λλ₯Ό 건λλ°μ΄μΌ νλ―λ‘ μ±λ₯ μ νλ‘ μ΄μ΄μ§ μ μμ΅λλ€. μ΄λ νΉν λκ·λͺ¨ λ°μ΄ν°μ μμ λλλ¬μ§λλ€.
- μΌκ΄μ± μλ κ²°κ³Ό: ν΄λΌμ΄μΈνΈκ° λ°μ΄ν°λ₯Ό νμ΄μ§λ€μ΄μ νλ λμ μλ‘μ΄ νλͺ©μ΄ μ½μ λκ±°λ μμ λλ©΄ κ²°κ³Όκ° μΌκ΄λμ§ μμ μ μμ΅λλ€. μλ₯Ό λ€μ΄, μ¬μ©μκ° κ±΄λλ°μ΄μ§κ±°λ μ¬λ¬ λ² νμλ μ μμ΅λλ€. μ΄λ₯Ό μ’ μ’ "ν¬ν 리λ(Phantom Read)" λ¬Έμ λΌκ³ ν©λλ€.
μ¬μ© μ¬λ‘:
- μ±λ₯μ΄ μ€μνμ§ μμ μ€μ κ·λͺ¨μ λ°μ΄ν°μ .
- λ°μ΄ν° μΌκ΄μ±μ΄ μ΅μ°μ μμκ° μλ μλ리μ€.
2. 컀μ κΈ°λ° νμ΄μ§λ€μ΄μ (Seek λ©μλ)
Seek λ©μλ λλ ν€μ νμ΄μ§λ€μ΄μ μΌλ‘λ μλ €μ§ μ»€μ κΈ°λ° νμ΄μ§λ€μ΄μ μ λ€μ νμ΄μ§ κ²°κ³Όμ μμμ μ μλ³νκΈ° μν΄ μ»€μλ₯Ό μ¬μ©νμ¬ μ€νμ κΈ°λ° νμ΄μ§λ€μ΄μ μ νκ³λ₯Ό ν΄κ²°ν©λλ€. 컀μλ μΌλ°μ μΌλ‘ λ°μ΄ν°μ μ νΉμ λ μ½λλ₯Ό λνλ΄λ λΆν¬λͺ ν λ¬Έμμ΄μ λλ€. μ΄λ λ λΉ λ₯Έ κ²μμ μν΄ λ°μ΄ν°λ² μ΄μ€μ κ³ μ μΈλ±μ±μ νμ©ν©λλ€.
μμ:
λ°μ΄ν°κ° μΈλ±μ±λ μ΄(μ: `id` λλ `created_at`)μ κΈ°μ€μΌλ‘ μ λ ¬λμλ€κ³ κ°μ νλ©΄, APIλ 첫 λ²μ§Έ μμ²κ³Ό ν¨κ» 컀μλ₯Ό λ°νν μ μμ΅λλ€:
GET /products?limit=20
μλ΅μλ λ€μμ΄ ν¬ν¨λ μ μμ΅λλ€:
{
"data": [...],
"next_cursor": "eyJpZCI6IDMwLCJjcmVhdGVkX2F0IjoiMjAyMy0xMC0yNCAxMDowMDowMCJ9"
}
λ€μ νμ΄μ§λ₯Ό κ²μνκΈ° μν΄ ν΄λΌμ΄μΈνΈλ `next_cursor` κ°μ μ¬μ©ν©λλ€:
GET /products?limit=20&cursor=eyJpZCI6IDMwLCJjcmVhdGVkX2F0IjoiMjAyMy0xMC0yNCAxMDowMDowMCJ9
μ₯μ :
- μ±λ₯ ν₯μ: 컀μ κΈ°λ° νμ΄μ§λ€μ΄μ μ νΉν λκ·λͺ¨ λ°μ΄ν°μ μμ μ€νμ κΈ°λ° νμ΄μ§λ€μ΄μ λ³΄λ€ ν¨μ¬ λ λμ μ±λ₯μ μ 곡ν©λλ€. λ§μ μμ λ μ½λλ₯Ό 건λλΈ νμκ° μμ΅λλ€.
- λ μΌκ΄λ κ²°κ³Ό: λͺ¨λ λ°μ΄ν° μμ λ¬Έμ μ λ©΄μμΈ κ²μ μλμ§λ§, 컀μ κΈ°λ° νμ΄μ§λ€μ΄μ μ μΌλ°μ μΌλ‘ μ€νμ κΈ°λ° νμ΄μ§λ€μ΄μ λ³΄λ€ μ½μ λ° μμ μ λ κ°ν©λλ€. μ΄λ μ λ ¬μ μ¬μ©λλ μΈλ±μ±λ μ΄μ μμ μ±μ μμ‘΄ν©λλ€.
λ¨μ :
- λ 볡μ‘ν ꡬν: 컀μ κΈ°λ° νμ΄μ§λ€μ΄μ μ μλ²μ ν΄λΌμ΄μΈνΈ μμͺ½ λͺ¨λμμ λ 볡μ‘ν λ‘μ§μ΄ νμν©λλ€. μλ²λ 컀μλ₯Ό μμ±νκ³ ν΄μν΄μΌ νλ©°, ν΄λΌμ΄μΈνΈλ νμ μμ²μμ 컀μλ₯Ό μ μ₯νκ³ μ λ¬ν΄μΌ ν©λλ€.
- μ μ°μ± λΆμ‘±: 컀μ κΈ°λ° νμ΄μ§λ€μ΄μ μ μΌλ°μ μΌλ‘ μμ μ μΈ μ λ ¬ μμκ° νμν©λλ€. μ λ ¬ κΈ°μ€μ΄ μμ£Ό λ³κ²½λλ κ²½μ° κ΅¬ννκΈ° μ΄λ €μΈ μ μμ΅λλ€.
- 컀μ λ§λ£: 컀μλ νΉμ κΈ°κ° νμ λ§λ£λ μ μμΌλ―λ‘ ν΄λΌμ΄μΈνΈκ° μ΄λ₯Ό μλ‘κ³ μΉ¨ν΄μΌ ν©λλ€. μ΄λ ν΄λΌμ΄μΈνΈ μΈ‘ ꡬνμ 볡μ‘μ±μ λν©λλ€.
μ¬μ© μ¬λ‘:
- μ±λ₯μ΄ μ€μν λκ·λͺ¨ λ°μ΄ν°μ .
- λ°μ΄ν° μΌκ΄μ±μ΄ μ€μν μλ리μ€.
- μμ μ μΈ μ λ ¬ μμκ° νμν API.
3. ν€μ νμ΄μ§λ€μ΄μ (Keyset Pagination)
ν€μ νμ΄μ§λ€μ΄μ μ νΉμ ν€(λλ ν€μ μ‘°ν©) κ°μ μ¬μ©νμ¬ λ€μ νμ΄μ§ κ²°κ³Όμ μμμ μ μλ³νλ 컀μ κΈ°λ° νμ΄μ§λ€μ΄μ μ λ³νμ λλ€. μ΄ μ κ·Ό λ°©μμ λΆν¬λͺ ν 컀μκ° νμ μμ΄ κ΅¬νμ λ¨μνν μ μμ΅λλ€.
μμ:
λ°μ΄ν°κ° `id` μ€λ¦μ°¨μμΌλ‘ μ λ ¬λμλ€κ³ κ°μ νλ©΄, APIλ μλ΅μ `last_id`λ₯Ό λ°νν μ μμ΅λλ€:
GET /articles?limit=10
{
"data": [...],
"last_id": 100
}
λ€μ νμ΄μ§λ₯Ό κ²μνκΈ° μν΄ ν΄λΌμ΄μΈνΈλ `last_id` κ°μ μ¬μ©ν©λλ€:
GET /articles?limit=10&after_id=100
κ·Έλ¬λ©΄ μλ²λ λ°μ΄ν°λ² μ΄μ€μμ `id`κ° `100`λ³΄λ€ ν° κΈ°μ¬λ₯Ό 쿼리ν©λλ€.
μ₯μ :
- λ κ°λ¨ν ꡬν: ν€μ νμ΄μ§λ€μ΄μ μ 볡μ‘ν 컀μ μΈμ½λ© λ° λμ½λ©μ΄ νμ μμΌλ―λ‘ μ»€μ κΈ°λ° νμ΄μ§λ€μ΄μ λ³΄λ€ κ΅¬ννκΈ°κ° λ μ¬μ΄ κ²½μ°κ° λ§μ΅λλ€.
- μ±λ₯ ν₯μ: 컀μ κΈ°λ° νμ΄μ§λ€μ΄μ κ³Ό λ§μ°¬κ°μ§λ‘, ν€μ νμ΄μ§λ€μ΄μ μ λκ·λͺ¨ λ°μ΄ν°μ μ λν΄ λ°μ΄λ μ±λ₯μ μ 곡ν©λλ€.
λ¨μ :
- κ³ μ ν€ νμ: ν€μ νμ΄μ§λ€μ΄μ μ λ°μ΄ν°μ μ κ° λ μ½λλ₯Ό μλ³νκΈ° μν΄ κ³ μ ν ν€(λλ ν€μ μ‘°ν©)κ° νμν©λλ€.
- λ°μ΄ν° μμ μ λ―Όκ°: 컀μ κΈ°λ°κ³Ό λ§μ°¬κ°μ§λ‘, κ·Έλ¦¬κ³ μ€νμ λ³΄λ€ λ, μ λ ¬ μμμ μν₯μ λ―ΈμΉλ μ½μ λ° μμ μ λ―Όκ°ν μ μμ΅λλ€. μ μ€ν ν€ μ νμ΄ μ€μν©λλ€.
μ¬μ© μ¬λ‘:
- μ±λ₯μ΄ μ€μν λκ·λͺ¨ λ°μ΄ν°μ .
- κ³ μ ν€λ₯Ό μ¬μ©ν μ μλ μλ리μ€.
- λ κ°λ¨ν νμ΄μ§λ€μ΄μ ꡬνμ΄ νμν λ.
4. Seek λ©μλ (λ°μ΄ν°λ² μ΄μ€ νΉμ )
μΌλΆ λ°μ΄ν°λ² μ΄μ€λ ν¨μ¨μ μΈ νμ΄μ§λ€μ΄μ μ μ¬μ©ν μ μλ λ€μ΄ν°λΈ seek λ©μλλ₯Ό μ 곡ν©λλ€. μ΄λ¬ν λ©μλλ λ°μ΄ν°λ² μ΄μ€μ λ΄λΆ μΈλ±μ± λ° μΏΌλ¦¬ μ΅μ ν κΈ°λ₯μ νμ©νμ¬ νμ΄μ§λ€μ΄μ λ λ°©μμΌλ‘ λ°μ΄ν°λ₯Ό κ²μν©λλ€. μ΄λ λ³Έμ§μ μΌλ‘ λ°μ΄ν°λ² μ΄μ€ νΉμ κΈ°λ₯μ μ¬μ©νλ 컀μ κΈ°λ° νμ΄μ§λ€μ΄μ μ λλ€.
μμ (PostgreSQL):
PostgreSQLμ `ROW_NUMBER()` μλμ° ν¨μλ₯Ό μλΈμΏΌλ¦¬μ κ²°ν©νμ¬ seek κΈ°λ° νμ΄μ§λ€μ΄μ μ ꡬνν μ μμ΅λλ€. μ΄ μλ `events`λΌλ ν μ΄λΈμ κ°μ νλ©° νμμ€ν¬ν `event_time`μ κΈ°λ°μΌλ‘ νμ΄μ§λ€μ΄μ ν©λλ€.
SQL 쿼리:
SELECT * FROM (
SELECT
*,
ROW_NUMBER() OVER (ORDER BY event_time) as row_num
FROM
events
) as numbered_events
WHERE row_num BETWEEN :start_row AND :end_row;
μ₯μ :
- μ΅μ νλ μ±λ₯: λ°μ΄ν°λ² μ΄μ€ νΉμ seek λ©μλλ μΌλ°μ μΌλ‘ μ±λ₯μ λ§€μ° μ΅μ νλμ΄ μμ΅λλ€.
- λ¨μνλ ꡬν (κ²½μ°μ λ°λΌ): λ°μ΄ν°λ² μ΄μ€κ° νμ΄μ§λ€μ΄μ λ‘μ§μ μ²λ¦¬νμ¬ μ ν리μΌμ΄μ μ½λμ 볡μ‘μ±μ μ€μ λλ€.
λ¨μ :
- λ°μ΄ν°λ² μ΄μ€ μ’ μμ±: μ΄ μ κ·Ό λ°©μμ μ¬μ© μ€μΈ νΉμ λ°μ΄ν°λ² μ΄μ€μ λ°μ νκ² κ²°ν©λ©λλ€. λ°μ΄ν°λ² μ΄μ€λ₯Ό μ ννλ €λ©΄ μλΉν μ½λ λ³κ²½μ΄ νμν μ μμ΅λλ€.
- 볡μ‘μ± (κ²½μ°μ λ°λΌ): μ΄λ¬ν λ°μ΄ν°λ² μ΄μ€ νΉμ λ©μλλ₯Ό μ΄ν΄νκ³ κ΅¬ννλ κ²μ΄ 볡μ‘ν μ μμ΅λλ€.
μ¬μ© μ¬λ‘:
- λ€μ΄ν°λΈ seek λ©μλλ₯Ό μ 곡νλ λ°μ΄ν°λ² μ΄μ€λ₯Ό μ¬μ©ν λ.
- μ±λ₯μ΄ κ°μ₯ μ€μνκ³ λ°μ΄ν°λ² μ΄μ€ μ’ μμ±μ΄ νμ©λ λ.
μ¬λ°λ₯Έ νμ΄μ§λ€μ΄μ μ λ΅ μ ννκΈ°
μ μ ν νμ΄μ§λ€μ΄μ μ λ΅μ μ ννλ κ²μ λ€μμ ν¬ν¨ν μ¬λ¬ μμΈμ λ°λΌ λ¬λΌμ§λλ€:
- λ°μ΄ν°μ ν¬κΈ°: μμ λ°μ΄ν°μ μ κ²½μ° μ€νμ κΈ°λ° νμ΄μ§λ€μ΄μ μΌλ‘ μΆ©λΆν μ μμ΅λλ€. λκ·λͺ¨ λ°μ΄ν°μ μ κ²½μ° μ»€μ κΈ°λ° λλ ν€μ νμ΄μ§λ€μ΄μ μ΄ μΌλ°μ μΌλ‘ μ νΈλ©λλ€.
- μ±λ₯ μꡬμ¬ν: μ±λ₯μ΄ μ€μν κ²½μ° μ»€μ κΈ°λ° λλ ν€μ νμ΄μ§λ€μ΄μ μ΄ λ λμ μ νμ λλ€.
- λ°μ΄ν° μΌκ΄μ± μꡬμ¬ν: λ°μ΄ν° μΌκ΄μ±μ΄ μ€μν κ²½μ° μ»€μ κΈ°λ° λλ ν€μ νμ΄μ§λ€μ΄μ μ΄ μ½μ λ° μμ μ λν λ λμ 볡μλ ₯μ μ 곡ν©λλ€.
- ꡬν 볡μ‘μ±: μ€νμ κΈ°λ° νμ΄μ§λ€μ΄μ μ΄ κ΅¬ννκΈ° κ°μ₯ κ°λ¨νλ©°, 컀μ κΈ°λ° νμ΄μ§λ€μ΄μ μ λ 볡μ‘ν λ‘μ§μ΄ νμν©λλ€.
- λ°μ΄ν°λ² μ΄μ€ μ§μ: μ¬μ© μ€μΈ λ°μ΄ν°λ² μ΄μ€κ° ꡬνμ λ¨μνν μ μλ λ€μ΄ν°λΈ seek λ©μλλ₯Ό μ 곡νλμ§ κ³ λ €νμμμ€.
- API μ€κ³ κ³ λ €μ¬ν: APIμ μ λ°μ μΈ μ€κ³μ νμ΄μ§λ€μ΄μ μ΄ λ λμ λ§₯λ½μ μ΄λ»κ² λΆν©νλμ§ μκ°ν΄λ³΄μμμ€. νμ€νλ μλ΅μ μν΄ JSON:API μ¬μ μ¬μ©μ κ³ λ €νμμμ€.
ꡬν λͺ¨λ² μ¬λ‘
μ΄λ€ νμ΄μ§λ€μ΄μ μ λ΅μ μ ννλ λ€μ λͺ¨λ² μ¬λ‘λ₯Ό λ°λ₯΄λ κ²μ΄ μ€μν©λλ€:
- μΌκ΄λ μ΄λ¦ μ§μ κ·μΉ μ¬μ©: νμ΄μ§λ€μ΄μ νλΌλ―Έν°μ μΌκ΄λκ³ μ€λͺ μ μΈ μ΄λ¦(μ: `offset`, `limit`, `cursor`, `page`, `page_size`)μ μ¬μ©νμμμ€.
- κΈ°λ³Έκ° μ 곡: ν΄λΌμ΄μΈνΈ μΈ‘ ꡬνμ λ¨μννκΈ° μν΄ νμ΄μ§λ€μ΄μ νλΌλ―Έν°μ ν©λ¦¬μ μΈ κΈ°λ³Έκ°μ μ 곡νμμμ€. μλ₯Ό λ€μ΄, κΈ°λ³Έ `limit`μΌλ‘ 25 λλ 50μ΄ μΌλ°μ μ λλ€.
- μ λ ₯ νλΌλ―Έν° κ²μ¦: μ ν¨νμ§ μκ±°λ μ μμ μΈ μ λ ₯μ λ°©μ§νκΈ° μν΄ νμ΄μ§λ€μ΄μ νλΌλ―Έν°λ₯Ό κ²μ¦νμμμ€. `offset`κ³Ό `limit`μ΄ μμκ° μλ μ μμΈμ§, κ·Έλ¦¬κ³ `limit`μ΄ ν©λ¦¬μ μΈ μ΅λκ°μ μ΄κ³Όνμ§ μλμ§ νμΈνμμμ€.
- νμ΄μ§λ€μ΄μ λ©νλ°μ΄ν° λ°ν: μ΄ νλͺ© μ, νμ¬ νμ΄μ§, λ€μ νμ΄μ§, μ΄μ νμ΄μ§(ν΄λΉνλ κ²½μ°)μ λν μ 보λ₯Ό ν΄λΌμ΄μΈνΈμκ² μ 곡νκΈ° μν΄ API μλ΅μ νμ΄μ§λ€μ΄μ λ©νλ°μ΄ν°λ₯Ό ν¬ν¨μν€μμμ€. μ΄ λ©νλ°μ΄ν°λ ν΄λΌμ΄μΈνΈκ° λ°μ΄ν°μ μ λ ν¨κ³Όμ μΌλ‘ νμνλ λ° λμμ΄ λ μ μμ΅λλ€.
- HATEOAS(μ ν리μΌμ΄μ μνμ μμ§μΌλ‘μ νμ΄νΌλ―Έλμ΄) μ¬μ©: HATEOASλ κ΄λ ¨ 리μμ€μ λν λ§ν¬λ₯Ό API μλ΅μ ν¬ν¨μν€λ RESTful API μ€κ³ μμΉμ λλ€. νμ΄μ§λ€μ΄μ μ κ²½μ°, μ΄λ λ€μ λ° μ΄μ νμ΄μ§μ λν λ§ν¬λ₯Ό ν¬ν¨νλ κ²μ μλ―Έν©λλ€. μ΄λ₯Ό ν΅ν΄ ν΄λΌμ΄μΈνΈλ URLμ νλμ½λ©ν νμ μμ΄ μ¬μ© κ°λ₯ν νμ΄μ§λ€μ΄μ μ΅μ μ λμ μΌλ‘ λ°κ²¬ν μ μμ΅λλ€.
- μ£μ§ μΌμ΄μ€λ₯Ό μ°μνκ² μ²λ¦¬: μ ν¨νμ§ μμ 컀μ κ°μ΄λ λ²μλ₯Ό λ²μ΄λ μ€νμ κ³Ό κ°μ μ£μ§ μΌμ΄μ€λ₯Ό μ°μνκ² μ²λ¦¬νμμμ€. ν΄λΌμ΄μΈνΈκ° λ¬Έμ λ₯Ό ν΄κ²°νλ λ° λμμ΄ λλλ‘ μ μ΅ν μ€λ₯ λ©μμ§λ₯Ό λ°ννμμμ€.
- μ±λ₯ λͺ¨λν°λ§: μ μ¬μ μΈ λ³λͺ© νμμ μλ³νκ³ μ±λ₯μ μ΅μ ννκΈ° μν΄ νμ΄μ§λ€μ΄μ ꡬνμ μ±λ₯μ λͺ¨λν°λ§νμμμ€. λ°μ΄ν°λ² μ΄μ€ νλ‘νμΌλ§ λꡬλ₯Ό μ¬μ©νμ¬ μΏΌλ¦¬ μ€ν κ³νμ λΆμνκ³ λλ¦° 쿼리λ₯Ό μλ³νμμμ€.
- API λ¬Έμν: μ¬μ©λ νμ΄μ§λ€μ΄μ μ λ΅, μ¬μ© κ°λ₯ν νλΌλ―Έν° λ° νμ΄μ§λ€μ΄μ λ©νλ°μ΄ν° νμμ λν μμΈν μ 보λ₯Ό ν¬ν¨νμ¬ APIμ λν λͺ ννκ³ ν¬κ΄μ μΈ λ¬Έμλ₯Ό μ 곡νμμμ€. Swagger/OpenAPIμ κ°μ λꡬλ λ¬Έμνλ₯Ό μλννλ λ° λμμ΄ λ μ μμ΅λλ€.
- API λ²μ κ΄λ¦¬ κ³ λ €: APIκ° λ°μ ν¨μ λ°λΌ νμ΄μ§λ€μ΄μ μ λ΅μ λ³κ²½νκ±°λ μλ‘μ΄ κΈ°λ₯μ λμ ν΄μΌ ν μ μμ΅λλ€. κΈ°μ‘΄ ν΄λΌμ΄μΈνΈκ° μ€λ¨λμ§ μλλ‘ API λ²μ κ΄λ¦¬λ₯Ό μ¬μ©νμμμ€.
GraphQLμ μ΄μ©ν νμ΄μ§λ€μ΄μ
μμ μλ REST APIμ μ€μ μ λμμ§λ§, GraphQL APIλ‘ μμ ν λλ νμ΄μ§λ€μ΄μ μ λ§€μ° μ€μν©λλ€. GraphQLμ νμ΄μ§λ€μ΄μ μ μν λͺ κ°μ§ λ΄μ₯ λ©μ»€λμ¦μ μ 곡νλ©°, λ€μμ ν¬ν¨ν©λλ€:
- μ°κ²° νμ (Connection Types): GraphQL μ°κ²° ν¨ν΄μ νμ΄μ§λ€μ΄μ μ ꡬννλ νμ€νλ λ°©λ²μ μ 곡ν©λλ€. μ΄λ `edges` νλ(λ Έλ λͺ©λ‘ ν¬ν¨)μ `pageInfo` νλ(νμ¬ νμ΄μ§μ λν λ©νλ°μ΄ν° ν¬ν¨)λ₯Ό ν¬ν¨νλ μ°κ²° νμ μ μ μν©λλ€.
- μΈμ(Arguments): GraphQL 쿼리λ `first`(κ²μν νλͺ© μ), `after`(λ€μ νμ΄μ§μ μμμ μ λνλ΄λ 컀μ), `last`(λͺ©λ‘ λμμ κ²μν νλͺ© μ), `before`(μ΄μ νμ΄μ§μ λμ μ λνλ΄λ 컀μ)μ κ°μ νμ΄μ§λ€μ΄μ μΈμλ₯Ό λ°μ μ μμ΅λλ€.
μμ:
μ°κ²° ν¨ν΄μ μ¬μ©νμ¬ μ¬μ©μλ₯Ό νμ΄μ§λ€μ΄μ νλ GraphQL 쿼리λ λ€μκ³Ό κ°μ μ μμ΅λλ€:
query {
users(first: 10, after: "YXJyYXljb25uZWN0aW9uOjEw") {
edges {
node {
id
name
}
cursor
}
pageInfo {
hasNextPage
endCursor
}
}
}
μ΄ μΏΌλ¦¬λ 컀μ "YXJyYXljb25uZWN0aW9uOjEw" μ΄νμ 첫 10λͺ μ μ¬μ©μλ₯Ό κ²μν©λλ€. μλ΅μλ μ£μ§ λͺ©λ‘(κ°κ° μ¬μ©μ λ Έλμ 컀μ ν¬ν¨)κ³Ό λ€μ νμ΄μ§κ° μλμ§ μ¬λΆ λ° λ€μ νμ΄μ§μ 컀μλ₯Ό λνλ΄λ `pageInfo` κ°μ²΄κ° ν¬ν¨λ©λλ€.
API νμ΄μ§λ€μ΄μ μ λν κΈλ‘λ² κ³ λ €μ¬ν
API νμ΄μ§λ€μ΄μ μ μ€κ³νκ³ κ΅¬νν λ λ€μκ³Ό κ°μ κΈλ‘λ² μμλ₯Ό κ³ λ €νλ κ²μ΄ μ€μν©λλ€:
- μκ°λ: APIκ° μκ°μ λ―Όκ°ν λ°μ΄ν°λ₯Ό λ€λ£¨λ κ²½μ° μκ°λλ₯Ό μ¬λ°λ₯΄κ² μ²λ¦¬ν΄μΌ ν©λλ€. λͺ¨λ νμμ€ν¬νλ₯Ό UTCλ‘ μ μ₯νκ³ ν΄λΌμ΄μΈνΈ μΈ‘μμ μ¬μ©μμ νμ§ μκ°λλ‘ λ³ννμμμ€.
- ν΅ν: APIκ° κΈμ μ κ°μΉλ₯Ό λ€λ£¨λ κ²½μ° κ° κ°μ λν ν΅νλ₯Ό μ§μ νμμμ€. μΌκ΄μ±μ 보μ₯νκ³ λͺ¨νΈμ±μ νΌνκΈ° μν΄ ISO 4217 ν΅ν μ½λλ₯Ό μ¬μ©νμμμ€.
- μΈμ΄: APIκ° μ¬λ¬ μΈμ΄λ₯Ό μ§μνλ κ²½μ° νμ§νλ μ€λ₯ λ©μμ§μ λ¬Έμλ₯Ό μ 곡νμμμ€. `Accept-Language` ν€λλ₯Ό μ¬μ©νμ¬ μ¬μ©μμ μ νΈ μΈμ΄λ₯Ό κ²°μ νμμμ€.
- λ¬Ένμ μ°¨μ΄: μ¬μ©μκ° APIμ μνΈ μμ©νλ λ°©μμ μν₯μ λ―ΈμΉ μ μλ λ¬Ένμ μ°¨μ΄λ₯Ό μΈμνμμμ€. μλ₯Ό λ€μ΄, λ μ§ λ° μ«μ νμμ κ΅κ°λ§λ€ λ€λ¦ λλ€.
- λ°μ΄ν° νλΌμ΄λ²μ κ·μ : κ°μΈ λ°μ΄ν°λ₯Ό μ²λ¦¬ν λ GDPR(μΌλ° λ°μ΄ν° λ³΄νΈ κ·μ ) λ° CCPA(μΊλ¦¬ν¬λμ μλΉμ κ°μΈ μ 보 보νΈλ²)μ κ°μ λ°μ΄ν° νλΌμ΄λ²μ κ·μ μ μ€μνμμμ€. μ μ ν λμ λ©μ»€λμ¦μ κ°μΆκ³ μ¬μ©μμ λ°μ΄ν°λ₯Ό λ¬΄λ¨ μ‘μΈμ€λ‘λΆν° 보νΈν΄μΌ ν©λλ€.
κ²°λ‘
API νμ΄μ§λ€μ΄μ μ νμ₯ κ°λ₯νκ³ ν¨μ¨μ μΈ λ°μ΄ν° κ²μ μμ€ν μ ꡬμΆνκΈ° μν νμ κΈ°μ μ λλ€. λκ·λͺ¨ λ°μ΄ν°μ μ λ μκ³ κ΄λ¦¬νκΈ° μ¬μ΄ λ©μ΄λ¦¬λ‘ λλμΌλ‘μ¨ νμ΄μ§λ€μ΄μ μ μ±λ₯μ ν₯μμν€κ³ , λ©λͺ¨λ¦¬ μλΉλ₯Ό μ€μ΄λ©°, μ¬μ©μ κ²½νμ ν₯μμν΅λλ€. μ¬λ°λ₯Έ νμ΄μ§λ€μ΄μ μ λ΅μ μ ννλ κ²μ λ°μ΄ν°μ ν¬κΈ°, μ±λ₯ μꡬμ¬ν, λ°μ΄ν° μΌκ΄μ± μꡬμ¬ν, ꡬν 볡μ‘μ± λ± μ¬λ¬ μμΈμ λ°λΌ λ¬λΌμ§λλ€. μ΄ κ°μ΄λμ μμ½λ λͺ¨λ² μ¬λ‘λ₯Ό λ°λ₯΄λ©΄ μ¬μ©μμ λΉμ¦λμ€μ μꡬλ₯Ό μΆ©μ‘±νλ κ²¬κ³ νκ³ μ λ’°ν μ μλ νμ΄μ§λ€μ΄μ μ루μ μ ꡬνν μ μμ΅λλ€.
μ΅μ μ μ±λ₯κ³Ό νμ₯μ±μ 보μ₯νκΈ° μν΄ νμ΄μ§λ€μ΄μ ꡬνμ μ§μμ μΌλ‘ λͺ¨λν°λ§νκ³ μ΅μ ννλ κ²μ μμ§ λ§μμμ€. λ°μ΄ν°κ° μ¦κ°νκ³ APIκ° λ°μ ν¨μ λ°λΌ νμ΄μ§λ€μ΄μ μ λ΅μ μ¬νκ°νκ³ κ·Έμ λ°λΌ ꡬνμ μ‘°μ ν΄μΌ ν μλ μμ΅λλ€.